package com.guanyua.eims.common.websocket;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@ServerEndpoint(value = "/webSocket/{customerId}")
@Component
@Slf4j
public class WebsocketServer {

    private static int onlineCount = 0;
    private static Map<Long, WebsocketServer> webSocketSet = new ConcurrentHashMap<>();
    private Session session;
    private Long customerId;    //  客户id

    @OnOpen
    public void onOpen(@PathParam("customerId") String customerId, Session session, EndpointConfig config) {
        this.session = session;
        this.customerId = Long.valueOf(customerId);

        log.info("客户【" + customerId + "】加入连接");

        if(webSocketSet.get(customerId) != null){
            log.info("客户【" + webSocketSet.get(customerId).customerId + "】有连接未关闭，sessionId【" + webSocketSet.get(customerId).session.getId() + "】");
            try {
                webSocketSet.get(customerId).session.close();
            } catch (Exception e) {
                log.error("连接失败【{}】", e.getMessage());
            }
        }

        //  加入map
        webSocketSet.put(Long.valueOf(customerId), this);

        try {
            //  连接成功回复
            session.getBasicRemote().sendText("onOpenSuccess");
        } catch (Exception e) {
            log.error("连接成功后回复消息失败【{}】", e.getMessage());
        }
    }

    @OnClose
    public void onClose() {
        try {
            webSocketSet.remove(customerId);
            log.info("关闭连接");
        } catch (Exception e){
            log.error("关闭消息失败");
        }
    }

    @OnMessage
    public void onMessage(String message, Session session) {
        synchronized(session) {
            if(!message.equals("ping")){
                log.info("【" + webSocketSet.get(customerId).customerId + "】发来消息：" + message);
            }
            try {
                //  回复消息
                session.getBasicRemote().sendText(message);
            } catch (Exception e) {
                log.error("发送消息失败【{}】", e.getMessage());
            }
        }
    }

    @OnError
    public void onError(Session session, Throwable error) {
        log.error("连接异常（sessionId【{}】，错误消息【{}】）", session.getId(), error.getMessage());
    }

    /**
     * 发送消息
     * @param customerId    客户id
     * @param message   消息内容
     */
    public static void sendMessage(Long customerId, String message) {
        try {
            log.info("向客户【{}】发送消息：【{}】", webSocketSet.get(customerId).customerId, message);
            webSocketSet.get(customerId).session.getBasicRemote().sendText(message);
        } catch (Exception e) {
            log.error("发送消息失败【{}】", e.getMessage());
        }
//        this.session.getBasicRemote().sendText(message);
        //this.session.getAsyncRemote().sendText(message);
    }

    public static synchronized int getOnlineCount() {
        return onlineCount;
    }

    public static synchronized void addOnlineCount() {
        onlineCount++;
    }

    public static synchronized void subOnlineCount() {
        onlineCount--;
    }

}